#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>

#define COMMAND_MAX 200
#define COMMAND_PROMPT_MAX 20
void show_tips()
{
    fprintf(stdout,"\rCommand not recognized. Valid commands are\n");
    fprintf(stdout,"\rquit  : close program\n");
    fprintf(stdout, "\rbg you command : command will process background\n");
    fprintf(stdout,"\ryou command  : write you command here like real shell, "
                   "but just support redirect input and out   <  and > this two signal\n" );

    fflush(stdout);
}
int main(int argc,char *argv[])
{
    char command_buf[COMMAND_MAX];
    char system_cmd[COMMAND_MAX];
    char check_buf[COMMAND_MAX];
    char re_in[COMMAND_MAX];
    char re_out[COMMAND_MAX];
    char command_prompt[COMMAND_PROMPT_MAX]="->";
    unsigned int len = 0;

    char *env_value = getenv("COMMAND_PROMPT");
    if (env_value != NULL && strlen(env_value)<COMMAND_PROMPT_MAX)
    {
        strcpy(command_prompt,env_value);
    }
    FILE * input_stream = stdin;
    FILE * output_stream = stdout;
    fprintf(stdout,"\n%s",command_prompt);
    fflush(stdout);

    while(fgets(command_buf,sizeof(command_buf),stdin)!=NULL)
    {
        command_buf[strlen(command_buf)-1]=0;
        memset(system_cmd,0,sizeof (system_cmd));
        memset(re_in,0,sizeof (re_in));
        memset(re_out,0,sizeof (re_out));
        len = strlen(command_buf);
        int flag = 0;
        for(int i=0;i<len;i++)
        {
            if (command_buf[i]=='>')
            {
                if (re_out[0]!=0)
                    goto ccc;
                flag =1;
                i++;
                while(i<len && command_buf[i]==' ')
                    i++;
                for(int j=0;i<len;j++,i++)
                {
                    if (command_buf[i]!=' ')
                        re_out[j]=command_buf[i];
                    else
                        break;

                }
            }
            if (command_buf[i]=='<')
            {
                if (re_in[0]!=0)
                    goto ccc;
                flag =1;
                i++;
                while(i<len && command_buf[i]==' ')
                    i++;
                for(int j=0;i<len;j++,i++)
                {
                    if (command_buf[i]!=' ')
                        re_in[j]=command_buf[i];
                    else
                        break;

                }
            }
            if(flag==1 && i<len && command_buf[i]!=' ' )
                goto ccc;
            system_cmd[i]=command_buf[i];
        }


        len  = strlen(system_cmd);
        memset(check_buf,0,sizeof (check_buf));
        for (int i=0,j=0;i<len;i++)
        {
            if (system_cmd[i]==' ')
                continue;
            check_buf[j]=system_cmd[i];
            j++;
        }
        if(strcmp(check_buf,"quit")==0)
            return 0;
        memset(check_buf,0,sizeof (check_buf));
        for (int i=0,j=0;i<len;i++)
        {
            if (system_cmd[i]==' ')
            {
                if (check_buf[0]!=0)
                {
                    flag=i;
                    break;
                }
                else
                    continue;
            }
            check_buf[j]=system_cmd[i];
            j++;
        }
        if(strcmp(check_buf,"bg")==0)
        {
            pid_t back = fork();
            if (back==0)
            {
                int out_tmp = dup(fileno(stdout));
                int in_tmp = dup(fileno(stdin));
                fprintf(stdout, "\n%s", command_prompt);
                fflush(stdout);
                if (re_in[0]!=0)
                {
                    int tmp = open(re_in,O_RDONLY);
                    dup2(tmp,0);
                }

                if (re_out[0]!=0)
                {
                    int tmp = open(re_out,O_WRONLY);
                    dup2(tmp,1);
                }
                else
                {
                    int tmp = open("a.txt",O_WRONLY);
                    dup2(tmp,1);
                }

                system( system_cmd+flag);
                fclose(stdout);
                fclose(stdin);
                stdout = fdopen(out_tmp,"w");
                stdin = fdopen(in_tmp,"r");

                return 0;
            }
            else
            {
                continue;
            }
        }
        else
        {
            int out_tmp = dup(fileno(stdout));
            int in_tmp = dup(fileno(stdin));
            if (re_in[0]!=0)
                freopen(re_in,"r",stdin);
            if (re_out[0]!=0)
                freopen(re_out,"w",stdout);
            system( command_buf);
            fclose(stdout);
            fclose(stdin);
            stdout = fdopen(out_tmp,"w");
            stdin = fdopen(in_tmp,"r");
            fprintf(stdout,"\n%s",command_prompt);
            fflush(stdout);
            continue;
        }

       ccc:
        show_tips();
        fprintf(stdout,"\n%s",command_prompt);
        fflush(stdout);

    }


    return 0;
}
